/*!
    Copyright (c) 2025, Aprilhome.
    brief:
    Change Logs:
    Date           Author       Notes
    2025/04/30     Aprilhome    first version
*/
#ifndef __AHFS_H__
#define __AHFS_H__
/* Include files */
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "ahfs_config.h"

/* Exported pre-processor symbols/macros ('#define') */
#define AHFS_VERSION (0x0100)  // 版本号,eg:0x0103 表示1.3版本
#define AHFS_RES_OK (0)                /* Successful */
#define AHFS_RES_ERR_PTR (-1)          /* Pointer Error */
#define AHFS_RES_ERR_RW (-2)           /* R/W Error */
#define AHFS_RES_ERR_FS (-3)           /* File System Error */
#define AHFS_RES_ERR_SPACE (-4)        /* Space Not Enough Error */
#define AHFS_RES_ERR_OVERFLOW (-5)     /* Overflow Error */

/* Exported type definitions ('typedef') */
struct ahfs_rtc
{
    uint8_t      year;      /* year 00-99 */
    uint8_t      month;     /* month  01-12*/
    uint8_t      date;      /* day of month 01-31*/
    uint8_t      hour ;     /* hour 00-23*/
    uint8_t      minute;    /* minutes 00-59*/
    uint8_t      second;    /* seconds 00-59*/
};

/* 元数据结构（扇区0），每次创建新索引后要更新*/
struct ahfs_metadata 
{
    /* 存储布局参数 */
    uint32_t magic_number;          // 魔术字
    uint16_t version;               // 版本号,eg:0x0103 表示1.3版本
    uint16_t sector_size;           // 扇区大小，单位：字节，=AHFS_MAX_SS,sd为512
    uint32_t total_sectors;         // 扇区总数，单位：扇区
    uint32_t max_indexes;           // 索引总数，单位：索引
    uint32_t physical_metadata_sector;  // 元数据所在物理扇区，通常为0
    uint32_t physical_index_start_sector;    // 物理索引区起始扇区，通常为1
    uint32_t physical_data_start_sector;     // 物理数据区起始扇区

    /* 状态跟踪参数 */
    uint32_t logical_index_start_sector;     // 逻辑索引区起始扇区，环形
    uint32_t logical_data_start_sector;      // 逻辑数据区起始扇区，环形
    uint32_t active_index_count;    // 已激活索引数量（<=max_indexes），从1开始，并达到最大值后不再增加保持为最大值
    uint32_t current_index_id;      // 当前操作的索引编号（持续递增，可能超过max_indexex）
    uint32_t current_data_sector;   // 当前操作的数据扇区，始终是整扇区    写数据后也要更新
    uint32_t used_data_sectors;     // 已使用的数据扇区数量（不包括正在使用的不完整的扇区，但是包括一个文件最后的不完整的扇区）
    
    /* 校验参数 */
    uint16_t crc16;                 // CRC16校验值，对除crc16外的所有字段进行校验
};
/* 索引数据结构（索引区），每次创建新索引后要更新*/ 
struct ahfs_index
{
    uint32_t index_id;          // 索引编号，从0开始，并且不会清零，=metadata.current_index_id
    uint32_t timestamp;         // 时间戳 支持到2037年
    uint32_t data_start_sector; // 本索引的数据区开始扇区号
    uint32_t data_bytes;        // 数据长度(单位：字节)     写数据后也要更新
};

typedef struct ahfs_obj
{
    struct ahfs_metadata metadata;   // 元数据，持久化
    struct ahfs_index current_index; // 当前索引，临时

    /* 预计算参数（在初始化时根据metadata计算） */
    uint32_t total_index_sectors; // 索引区扇区总数
    uint32_t total_data_sectors;  // 数据区扇区总数
    uint32_t indexes_per_sector;  // 每个扇区的索引数量

    /* 读写缓存 */
    uint8_t buf[AHFS_SECTOR_SIZE]; // 读写缓存

    /* 操作函数 */
    uint32_t (*ahfs_get_current_timestamp)(void);                 // 获取当前时间戳
    void (*ahfs_put_serial)(uint8_t *, uint16_t);                // 向串口发送数据
    uint16_t (*ahfs_calculate_CRC16)(uint8_t *, uint16_t);       // 计算CRC16校验值
    int8_t (*ahfs_read_metadata_index_from_flash)(struct ahfs_metadata *,
                                                  struct ahfs_index *); // 从flash读取元数据和索引数据
    int8_t (*ahfs_write_metadata_index_to_flash)(struct ahfs_metadata *,
                                                 struct ahfs_index *); // 向flash写元数据和索引数据
    uint16_t (*ahfs_generate_file_info_format)(uint8_t *put_buf, struct ahfs_index *index); // 生成文件信息格式,不得超过128字节！！！
} ahfs_t;

// typedef struct ahfs_file_obj
/* Exported function prototypes */
int8_t ahfs_init_storage(void);
int8_t ahfs_init_fs(ahfs_t *fs);
int8_t ahfs_format(ahfs_t *fs, uint8_t format_mode);
int8_t ahfs_get_storage_space(ahfs_t *fs,
                              uint64_t *total_data_space, uint64_t *free_data_space,
                              uint32_t *total_index_count, uint32_t *free_index_count);
int8_t ahfs_create_file(ahfs_t *fs);
int8_t ahfs_write_file(ahfs_t *fs, uint8_t *buf, uint32_t size);
int8_t ahfs_sync(ahfs_t *fs);
int8_t ahfs_read_files_size(ahfs_t *fs,
                            uint32_t begin_index, uint32_t end_index,
                            uint32_t *files_size);
int8_t ahfs_read_files_to_serial(ahfs_t *fs, uint32_t begin_index, uint32_t end_index);
int8_t ahfs_read_files_list_to_serial(ahfs_t *fs);
int8_t ahfs_write_sector(uint32_t sector, uint8_t *buf);
int8_t ahfs_read_sector(uint32_t sector, uint8_t *buf);

/* Exported variable definitions */
#endif